#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "catalog.h"
#include "storage.h"
#include "page.h"
#include "plan.h"
#include "record.h"

// 系统表常量定义
const char *CAT_TABLES  = "_tables";  // 表信息系统表名
const char *CAT_COLUMNS = "_columns"; // 列信息系统表名

const uint32_t TABLES_PID  = 1;  // 表信息页ID
const uint32_t COLUMNS_PID = 2;  // 列信息页ID

// ===== 内存版本实现 =====

// 创建模式目录
// 返回值：创建的模式目录指针，失败返回NULL
Catalog* create_catalog() {
    Catalog* catalog = (Catalog*)malloc(sizeof(Catalog));
    catalog->tables = NULL;
    catalog->table_count = 0;
    return catalog;
}

// 释放模式目录及其资源
// 参数：
// - catalog: 要释放的模式目录指针
void free_catalog(Catalog* catalog) {
    if (catalog) {
        for (int i = 0; i < catalog->table_count; i++) {
            TableSchema* table = catalog->tables[i];
            free((void*)table->table_name);
            for (int j = 0; j < table->ncols; j++) {
                free((void*)table->cols[j].name);
            }
            free(table->cols);
            free(table);
        }
        free(catalog->tables);
        free(catalog);
    }
}

// 添加表到目录
// 参数：
// - catalog: 模式目录指针
// - table: 要添加的表结构
// 返回值：成功返回1，失败返回0（如表已存在）
int add_table_to_catalog(Catalog* catalog, TableSchema* table) {
    if (!catalog || !table) return 0;
    
    // 检查表是否已存在
    for (int i = 0; i < catalog->table_count; i++) {
        if (strcmp(catalog->tables[i]->table_name, table->table_name) == 0) {
            return 0; // 表已存在
        }
    }
    
    // 扩展表数组
    catalog->tables = realloc(catalog->tables, (catalog->table_count + 1) * sizeof(TableSchema*));
    catalog->tables[catalog->table_count] = table;
    catalog->table_count++;
    
    return 1;
}

// 从目录中查找表
TableSchema* find_table_in_catalog(Catalog* catalog, const char* table_name) {
    if (!catalog || !table_name) return NULL;
    
    for (int i = 0; i < catalog->table_count; i++) {
        if (strcmp(catalog->tables[i]->table_name, table_name) == 0) {
            return catalog->tables[i];
        }
    }
    
    return NULL;
}

// 从表中查找列 - 修复版本
int find_column_in_table(TableSchema* table, const char* column_name) {
    if (!table || !column_name) return 0;
    
    for (int i = 0; i < table->ncols; i++) {
        if (strcmp(table->cols[i].name, column_name) == 0) {
            // 只需要返回找到列的标志，不需要动态分配内存
            return 1;
        }
    }
    
    return 0;
}

// ===== 持久化版本实现 =====
static int ensure_page(uint32_t pid) {
    Page p;
    int rc = storage_read_page(pid, &p);
    if (rc != 0) {
        // 页面不存在，创建新页面
        page_init(&p);
        rc = storage_write_page(pid, &p);
        return rc;
    }
    return 0;
}

int catalog_bootstrap() {
    // 确保系统表页可用
    if (ensure_page(TABLES_PID) != 0) return -1;
    if (ensure_page(COLUMNS_PID) != 0) return -2;
    return 0;
}

// 注册表到目录
int catalog_register_table(const char* table_name, uint32_t root_pid) {
    Page p;
    int read_result = storage_read_page(TABLES_PID, &p);
    if (read_result != 0) {
        return read_result;
    }
    
    // 行 = RowHeader + name(varchar32) + root_pid(int)
    char root_pid_str[16];
    snprintf(root_pid_str, sizeof(root_pid_str), "%u", root_pid);
    
    const char *vals[2] = { table_name, root_pid_str };
    TableSchema s = { CAT_TABLES, 2, NULL, 0 };  // 添加root_pid初始化为0
    ColumnDef cols[2] = { {"name", TYPE_VARCHAR, 31}, {"root_pid", TYPE_INT, 0} };
    s.cols = cols;
    
    // 计算序列化所需空间并序列化
    int need = serialize_row(&s, vals, NULL, 0);
    
    uint8_t buf[128];
    int serialize_result = serialize_row(&s, vals, buf, sizeof(buf));
    // 修复：将判断条件从 != 0 改为 < 0
    if (serialize_result < 0) {
        return serialize_result;
    }
    
    // 插入行并写入页面
    int slot;
    int insert_result = page_insert(&p, buf, need, &slot);
    if (insert_result != 0) {
        return insert_result;
    }
    
    int write_result = storage_write_page(TABLES_PID, &p);
    
    return write_result;
}

int catalog_get_table(const char *name, TablesRow *out) {
    Page p;
    
    int read_result = storage_read_page(TABLES_PID, &p);
    if (read_result != 0) {
        return -1;
    }
    
    for (int i = 0;; i++) {
        const void *rec;
        uint16_t len;
        int get_result = page_get(&p, i, &rec, &len);
        if (get_result == -1) {
            break; // 没有更多记录
        } else if (get_result == -2 || get_result == -3) {
            continue; // 跳过已删除或无效的记录
        }
        TableSchema s = { CAT_TABLES, 2, NULL, 0 };  // 添加root_pid初始化为0
        ColumnDef cols[2] = { {"name", TYPE_VARCHAR, 31}, {"root_pid", TYPE_INT, 0} };
        s.cols = cols;
        char *vals[2];  // 只需要这个定义，用于deserialize_row的输出
        
        if (deserialize_row(&s, rec, len, vals, 2) == 0) {
            if (strcmp(vals[0], name) == 0) {
                strncpy(out->name, vals[0], 31);
                out->name[31] = '\0';
                out->root_pid = atoi(vals[1]);
                // 正确：free由deserialize_row动态分配的内存
                free(vals[0]);
                free(vals[1]);
                return 0;
            }
            // 正确：free由deserialize_row动态分配的内存
            free(vals[0]);
            free(vals[1]);
        }
    }
    
    return -1;
}

// 修改函数签名，将参数类型从ColumnType和uint16_t改为int
int catalog_add_column(const char *t, const char *c, int type, int max_len) {
    Page p;
    int read_result = storage_read_page(COLUMNS_PID, &p);
    if (read_result != 0) {
        return read_result;
    }
    
    // 为所有4个列提供有效的字符串值
    char type_str[16];
    char len_str[16];
    snprintf(type_str, sizeof(type_str), "%d", type);
    snprintf(len_str, sizeof(len_str), "%d", max_len);
    
    // 使用局部变量存储字符串，而不是直接使用函数参数
    char table_name[32];
    char col_name[32];
    strncpy(table_name, t, sizeof(table_name)-1);
    table_name[sizeof(table_name)-1] = '\0';
    strncpy(col_name, c, sizeof(col_name)-1);
    col_name[sizeof(col_name)-1] = '\0';
    
    // 数据完整性检查
    if (strlen(table_name) == 0 || strlen(col_name) == 0) {
        return -10;
    }
    
    const char *vals3[4] = { table_name, col_name, type_str, len_str };
    TableSchema s = { CAT_COLUMNS, 4, NULL, 0 };
    ColumnDef cols[4] = {
        {"table_name", TYPE_VARCHAR, 31},
        {"col_name",   TYPE_VARCHAR, 31},
        {"col_type",   TYPE_INT,     0 },
        {"max_len",    TYPE_INT,     0 }
    };
    s.cols = cols;
    
    // 计算序列化所需空间并序列化
    int need = serialize_row(&s, vals3, NULL, 0);
    
    uint8_t buf[128];
    int serialize_result = serialize_row(&s, vals3, buf, sizeof(buf));
    if (serialize_result < 0) {
        return serialize_result;
    }
    
    int slot;
    int insert_result = page_insert(&p, buf, need, &slot);
    if (insert_result != 0) {
        return insert_result;
    }
    
    // 直接写入页面，不进行复杂的验证逻辑
    int write_result = storage_write_page(COLUMNS_PID, &p);
    
    return write_result;
}

// 修复catalog_load_schema函数，正确设置table_name
int catalog_load_schema(const char *t, TableSchema *schema, ColumnDef *buf, int cap) {
    // 扫描 _columns 取出 t 的列定义
    Page p;
    int read_result = storage_read_page(COLUMNS_PID, &p);
    if (read_result != 0) {
        printf("DEBUG: Failed to read columns page, result=%d\n", read_result);
        return read_result;
    }
    
    int n = 0;
    // 修改遍历方式，确保遍历所有可能的slot，而不仅仅是顺序查找
    int max_slots_to_check = 100; // 设置一个合理的上限，防止无限循环
    
    // 获取页面头信息以了解实际的slot_count
    PageHeader* header = (PageHeader*)p.data;
    int actual_slot_count = header->slot_count;
    
    for (int i = 0; i < max_slots_to_check; i++) {
        const void *rec;
        uint16_t len;
        int get_result = page_get(&p, i, &rec, &len);
        
        TableSchema s = { CAT_COLUMNS, 4, NULL, 0 };
        ColumnDef cols[4] = {
            {"table_name", TYPE_VARCHAR, 31},
            {"col_name", TYPE_VARCHAR, 31},
            {"col_type", TYPE_INT, 0},
            {"max_len", TYPE_INT, 0}
        };
        s.cols = cols;
        char *vals[4];
        
        if (deserialize_row(&s, (const uint8_t*)rec, len, vals, 4) == 0) {
            if (strcmp(vals[0], t) == 0) {
                // 无论是否有缓冲区，都统计列数
                n++;
                // 只有在有有效缓冲区且未超出容量时才复制列定义
                if (buf != NULL && n <= cap) {
                    // 正确设置列名（注意这里需要使用strdup复制字符串）
                    buf[n-1].name = strdup(vals[1]);
                    buf[n-1].type = (ColumnType)atoi(vals[2]);
                    buf[n-1].max_len = atoi(vals[3]);
                }
            } else {
            }
            for (int k = 0; k < 4; k++) {
                free(vals[k]);
            }
        } 
    }
    
    // 如果提供了schema参数，则设置其字段
    if (schema != NULL) {
        // 注意：不直接覆盖table_name指针，避免内存泄漏
        schema->table_name = strdup(t);  // 修复：正确设置table_name
        schema->ncols = n;
        schema->cols = buf;
    }
    
    return (n > 0) ? 0 : -1;
}

// 向内存表结构中添加列
int add_column_to_table(TableSchema* table, const char* column_name, ColumnType column_type, uint16_t max_len) {
    if (!table || !column_name) return -1;
    
    // 检查列是否已存在
    for (int i = 0; i < table->ncols; i++) {
        if (strcmp(table->cols[i].name, column_name) == 0) {
            // 列已存在，更新类型和长度
            table->cols[i].type = column_type;
            table->cols[i].max_len = max_len;
            return 0;
        }
    }
    
    // 扩展列数组
    table->cols = realloc(table->cols, (table->ncols + 1) * sizeof(ColumnDef));
    
    // 添加新列
    table->cols[table->ncols].name = strdup(column_name);
    table->cols[table->ncols].type = column_type;
    table->cols[table->ncols].max_len = max_len;
    table->ncols++;
    
    return 0;
}

// 添加函数从系统表加载所有表结构到内存目录
// 修复catalog_load_all_tables函数，确保正确加载表结构
int catalog_load_all_tables(Catalog* catalog) {
    // 读取系统表_columns中的所有表定义
    Page tables_page;
    if (storage_read_page(TABLES_PID, &tables_page) != 0) {
        return -1;
    }
    
    for (int i = 0;; i++) {
        const void *rec;
        uint16_t len;
        if (page_get(&tables_page, i, &rec, &len) != 0) {
            break;
        }
        
        // 反序列化表记录以获取表名和root_pid
        TableSchema s = { CAT_TABLES, 2, NULL, 0 };
        ColumnDef cols[2] = { {"name", TYPE_VARCHAR, 31}, {"root_pid", TYPE_INT, 0} };
        s.cols = cols;
        char *table_vals[2];
        
        if (deserialize_row(&s, rec, len, table_vals, 2) == 0) {
            // 提取表名
            const char* table_name = table_vals[0];
            uint32_t root_pid = atoi(table_vals[1]);
            
            // 创建表结构
            TableSchema* table_schema = (TableSchema*)malloc(sizeof(TableSchema));
            if (!table_schema) {
                free(table_vals[0]);
                free(table_vals[1]);
                continue;
            }
            
            memset(table_schema, 0, sizeof(TableSchema)); // 初始化所有字段为0
            table_schema->table_name = strdup(table_name);
            table_schema->ncols = 0;
            table_schema->cols = NULL;
            table_schema->root_pid = root_pid;
            
            // 尝试加载表的列定义
            ColumnDef cols_buf[32]; // 为列定义分配足够的空间
            if (catalog_load_schema(table_name, table_schema, cols_buf, 32) == 0) {
                // 将表添加到目录
                if (table_schema->ncols > 0) {
                    add_table_to_catalog(catalog, table_schema);
                } else {
                    // 释放空表结构
                    char* temp_name = (char*)table_schema->table_name;
                    free(temp_name);
                    free(table_schema);
                }
            } else {
                char* temp_name = (char*)table_schema->table_name;
                free(temp_name);
                free(table_schema);
            }
            
            // 释放临时内存
            free(table_vals[0]);
            free(table_vals[1]);
        }
    }
    
    return 0;
}

TableSchema* create_table_schema_from_ast(ASTNode* node) {
    if (!node || node->type != NODE_CREATE_TABLE) {
        return NULL;
    }
    
    CreateTableStmt* stmt = (CreateTableStmt*)node->extra_data;
    
    TableSchema* table = (TableSchema*)malloc(sizeof(TableSchema));
    if (!table) {
        return NULL;
    }
    
    table->table_name = strdup(stmt->table_name);
    
    // 复制列定义
    table->cols = (ColumnDef*)malloc(stmt->column_count * sizeof(ColumnDef));
    for (int i = 0; i < stmt->column_count; i++) {
        table->cols[i].name = strdup(stmt->columns[i].name);
        table->cols[i].type = stmt->columns[i].type;
        table->cols[i].max_len = stmt->columns[i].length;
    }
    table->ncols = stmt->column_count;
    table->root_pid = 0; // 初始化root_pid为0
    
    return table;
}

// 添加全局目录指针
static Catalog* global_catalog = NULL;

// 获取全局目录
Catalog* get_global_catalog() {
    if (!global_catalog) {
        global_catalog = create_catalog();
    }
    return global_catalog;
}